package com.own.demo.lwf.utils.ownUtils;/**
 * @author liwenfeng
 * @date 2022/8/14 0014
 * @apinote
 */

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Stream;

/**
 * @version v1.0
 * @Description:
 * @Author Administrator
 * @Date 2022/8/14 0014 11:28
 * @copyright 李文峰
 */
public class IOAllUtilsDemo {
    public static void main(String[] args) throws IOException {
// File：文件或者目录（文件夹）的创建，删除，获取文件，获取目录属性等，但不能访问文件内容
                 // exists:是否存在
                 // isFile：是否是文件
                 // isDirectory：是否是文件夹

                 // boolean createNewFile：创建当前File对象描述的文件
                 // mkdir：创建当前File对象描述的文件夹，如果父路径不在不自动创建父路径
                 // mkdirs：创建当前File对象描述的文件夹，如果父路径不在不自动创建父路径

                 //renameTo（File dest）：dest为重命名文件或文件夹的抽象路径。同文件夹为重命名，不同文件夹为剪切

                 // delete:删除，只能删除空文件夹

                 //getAbsolutePath:获取当前file对象的绝对路径
                 // getPath:获取封装的路径
                 // getName：获取抽象路径下的文件或文件夹名
                 // length：file对象描述的文件的字节个数
                 // list：指定路径所有文件和目录并用String返回

        // 如果文件不存在就创建新文件
        File file = new File("D://demo.txt");
        boolean newFile = file.createNewFile();
        System.out.println(newFile);


    // FileUtils

        // readFileToString:读文件  readLines:读文件，返回的是List<String>
        System.out.println(FileUtils.readFileToString(file,"UTF-8"));
        System.out.println(FileUtils.readLines(file,"UTF-8"));

        // readFileToString:写文件
        FileUtils.writeStringToFile(file,"添加一行","UTF-8",true);
        System.out.println(FileUtils.readFileToString(file,"UTF-8"));

        // 删除文件或删除文件夹下所有文件，且永远不会抛异常
        // FileUtils.deleteDirectory(file);
        FileUtils.deleteQuietly(file);



 // **********************************************************NIO.2************************************************
 // nio.2为jdk7之后新增，解决File（同步阻塞，面向流）的方法少和报异常等问题，为同步非阻塞，支持面向缓存，基于通道的io操作。可看成是io的改进版,取代File
     /*
        1. Path:Path对象
        2.Paths：主要可用工厂模式创建Path对象
        3.Files：对目录（文件夹）或文件操作
    */



    // Files:
        Path path = Paths.get("./DesignPattern/src/practise/lios/demo/alice.txt");
        //按行读取全部内容
        List<String> lines = Files.readAllLines(path);
        lines.stream().limit(10).forEach(System.out::println);

        //按字节读取全部内容
        byte[] bytes = Files.readAllBytes(path);
        String bytesToString = new String(bytes, 0 , 100);
        System.out.println("bytes:\n" + bytesToString);

        //通过InputStream读取内容
        InputStream inputStream = Files.newInputStream(path);
        Scanner inputScanner = new Scanner(inputStream, String.valueOf(StandardCharsets.UTF_8));
        final int maxLine = 10;
        int line = 0;
        System.out.println("Input Stream:");
        while(inputScanner.hasNextLine() && line < maxLine) {
            String contents = inputScanner.nextLine();
            line ++;
            System.out.println(contents);
        }

        //通过OutputStream写内容到文件
        Path outputDirectory = Paths.get("output");
        //目录不存在的话创建目录
        if (! Files.exists(outputDirectory)) {
            Files.createDirectory(outputDirectory);
        }
        //将输出文件放入到新加的目录下
        Path outPath = outputDirectory.resolve("output.txt");
        boolean fileExists = Files.exists(outPath);
        OutputStream outputStream;
        if (fileExists) {
            outputStream = Files.newOutputStream(outPath, StandardOpenOption.APPEND);
        } else {
            outputStream = Files.newOutputStream(outPath, StandardOpenOption.CREATE);
        }
        outputStream.write(bytes, 0, 100);

        //文件移动、复制及删除
        Path parentPath = outputDirectory.toAbsolutePath().getParent();
        if (parentPath != null) {
            Path destinationFilePath = parentPath.resolve("output.txt");
            //如果文件存在则替换掉
            Path copyPath = Files.copy(outPath, destinationFilePath, StandardCopyOption.REPLACE_EXISTING);

            Path movedFilePath = parentPath.resolve("output1.txt");
            Path movedPath = Files.move(outPath, movedFilePath, StandardCopyOption.REPLACE_EXISTING);

            Files.delete(outputDirectory);
        }


        // Files获取文件的基本信息
        boolean fileExists2 = Files.exists(path);
        System.out.println("File exists: " + fileExists2);
        if (fileExists2) {
            boolean isHidden = Files.isHidden(path);
            System.out.println("File is hidden: " + isHidden);

            boolean isReadable = Files.isReadable(path);
            System.out.println("File is readable: " + isReadable);

            boolean isWritable = Files.isWritable(path);
            System.out.println("File is writable: " + isWritable);

            boolean isExecutable = Files.isExecutable(path);
            System.out.println("File is executable: " + isExecutable);

            boolean isDirectory = Files.isDirectory(path);
            System.out.println("File is directory: " + isDirectory);

            boolean isSymbolicLink = Files.isSymbolicLink(path);
            System.out.println("File is symbolic link: " + isSymbolicLink);

            boolean isRegularFile = Files.isRegularFile(path);
            if (isRegularFile) {
                long fileSize = Files.size(path);
                System.out.printf("File size: %.1fkB \n",(float)fileSize / 1024);
                //BasicFileAttributes包含上述的全部属性封装
                BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class);
                System.out.println("File size: " + attributes.size() + "bytes");
                System.out.println("File created at: " + attributes.creationTime());
                System.out.println("File last modified at: " + attributes.lastModifiedTime());
                System.out.println("File last accessed at: " + attributes.lastAccessTime());
            }
        }


        // 目录遍历
        try (Stream<Path> entries = Files.list(path)) {
            entries.forEach(p -> {
                if (Files.isDirectory(p)) {
                    System.out.println("Directory: " + p);
                } else {
                    System.out.println("File: " + p);
                }
            });
        }

        try (Stream<Path> entries = Files.walk(path)) {
            entries.forEach(p -> {
                if (Files.isDirectory(p)) {
                    System.out.println("Directory: " + p);
                } else {
                    System.out.println("File: " + p);
                }
            });
        }














    }
}
